JSXと<dialog>で組んだmodal window
$ const stopPropagation = useCallback((e: Event) => e.stopPropagation(), []);
を指定しておく。これにより<dialog>内をクリックしても閉じられないようにできる
onOpenを廃止、代わりにuseDialogの引数に設定するようにした
import pathは適当に修正すること
code:useDialog.ts
import type { Ref } from "../preact/mod.tsx";
import { useCallback, useEffect, useRef } from "../preact/hooks.ts";
export interface UseDialogInit {
onOpen?: () => void;
onClose?: () => void;
onCancel?: () => void;
};
export interface UseDialogResult {
ref: Ref<HTMLDialogElement>;
open: VoidFunction;
close: VoidFunction;
toggle: VoidFunction;
setOpen: (open: boolean) => void;
}
export const useDialog = (init?: UseDialogInit): UseDialogResult => {
const ref = useRef<HTMLDialogElement>(null);
const open = useCallback(() => {
ref.current?.showModal?.();
init?.onOpen?.();
const close = useCallback(() => ref.current?.close?.(), []);
const toggle = useCallback(() => ref.current?.open ? close() : open(), open); const setOpen = useCallback((open_: boolean) => open_ ? open() : close(), open); useEffect(() => {
if (!init?.onClose) return;
const onClose = init?.onClose;
ref.current?.addEventListener?.("close", onClose);
return () => { ref.current?.removeEventListener?.("close", onClose); };
useEffect(() => {
if (!init?.onCancel) return;
const onCancel = init?.onCancel;
ref.current?.addEventListener?.("cancel", onCancel);
return () => { ref.current?.removeEventListener?.("cancel", onCancel); };
return { ref, open, close, toggle, setOpen };
};
dialog用CSS
code:style.css
dialog::backdrop{
background-color:#000c;
}
dialog {
flex-direction: column;
align-items: center;
row-gap: 10px;
padding: 10px;
background: unset;
margin-top: unset;
margin-bottom: unset;
border: unset;
height: unset;
}
display: flex;
}
dialog > * {
background-color: var(--dropdown-menu-bg, #fff); border: 1px solid rgba(0,0,0,.2);
border-radius: 6px;
}
@media (min-width: 768px) {
dialog {
padding: 30px 0;
}
}